/*
 ** validation 提供系统各种表单项校验功能
 **
 ** Created By Cheney Hu (cheney@gmail.com) 2016/06/23
 */

(function() {
    'use strict';

    angular
        .module('elife')
        .service('VALIDATION', VALIDATION);

    // VALIDATION.$inject = [''];

    /** @ngInject */
    function VALIDATION() {
        /*
         ** invalid string check 非法字符校验
         **
         ** 校验项：
         ** 1、特殊字符
         ** 2、特殊名称，如admin、管理员
         ** 3、防SQL注入
         **
         ** @params
         **     str 校验的字符串
         **
         */
        this.invalidStringCheck = function(str) {
            if (str) {
                var items = new Array("~", "`", "!", "@", "#", "$", "%", "^", "&", "*", "{", "}", "[", "]", "(", ")");
                items.push(":", ";", "'", "\"", "|", "\\", "<", ">", "?", "/", "<<", ">>", "||", "//");
                items.push("！", "￥", "…", "（", "）", "—", "-", "+", "『", "』", "：", "“", "”", "【", "】", "、", "；", "‘", "’", "，", "。", "《", "》", "？");
                items.push("admin", "administrators", "administrator", "管理员", "系统管理员");
                items.push("select", "delete", "update", "insert", "create", "drop", "alter", "trancate");

                str = str.toLowerCase();

                for (var i = 0; i < items.length; i++) {
                    if (str.indexOf(items[i]) >= 0) {
                        return false;
                    }
                }
                return true;
            } else {
                return false;
            }
        };

        /*
         ** string check 字符校验
         **
         ** @params
         **     str 校验的字符串
         **
         ** @return true/false
         **
         */
        this.stringCheck = function(str) {
            var numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
            if (str) {
                for (var i = 0; i < numbers.length; i++) {
                    if (str.indexOf(numbers[i]) >= 0) {
                        return false;
                    }
                }
                return true;
            }
            return false;
        };

        /*
         ** Number check 字符校验
         **
         ** @params
         **     str 校验的字符串
         **
         ** @return true/false
         **
         */
        this.numberCheck = function(str) {
            if (str) {
                var pattern = /^\d*$/;
                if (pattern.test(str)) {
                    return false;
                } else {
                    return true;
                }
            }
            return false;
        };

        /*
         ** chinese string check 汉字校验
         **
         ** @params
         **     str 校验的字符串
         **
         ** @return true/false
         **
         */
        this.chineseCheck = function(str) {
            if (/[^\u0000-\u00FF]/.test(str)) {
                return true;
            }
            return false;
        };

        /*
         ** word check 字母加数字校验
         **
         ** @params
         **     str 校验的字符串
         **
         ** @return true/false
         **
         */
        this.wordCheck = function(str) {
            if (str) {
                if (/^[a-zA-Z\d]+$/.test(str)) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        };

        /*
         ** password check 密码校验，密码的规则为：（大写英文字母，小写英文字母，特殊字符，数字）中4选2，且密码长度要大于8位
         **
         ** @params
         **     str 校验的字符串
         **
         ** @return true/false
         **
         */
        this.passwordCheck = function(str) {
            if (str) {
                var patternArray = [
                    /([a-z])/,
                    /([A-Z])/,
                    /([0-9])/,
                    /([!,%,&,@,#,$,^,*,?,_,~])/
                ];
                var passwordStrength = 0;
                for (var i = 0; i < patternArray.length; i++) {
                    if (patternArray[i].test(str)) {
                        passwordStrength++;
                    }
                }
                //长度低于8位不验证，高于8位再验证
                if (str.length >= 8) {
                    if (passwordStrength >= 2) {
                        return true;
                    } else {
                        return false;
                    }
                } else {

                    return true;
                }
            } else {
                return false;
            }
        };

        /*
         ** string length check 字符长度校验
         **
         ** @params
         **     str 校验的字符串
         **     len 固定长度
         **     compare 比较 gt/lt/= 大于/小于/等于
         **
         ** @return true/false
         **
         */
        this.stringLengthCheck = function(str, len, compare) {
            if (str && len) {
                if (compare == 'lt' && str.length <= len) {
                    return true;
                }
                if (compare == 'gt' && str.length >= len) {
                    return true;
                }
                if (compare == '=' && str.length == len) {
                    return true;
                }
            }
            return false;
        };

        /*
         ** id check 身份证校验
         **
         ** @params
         **     str 校验的字符串
         **
         ** @return true/false
         **
         */
        this.idCheck = function(str) {
            str = str.toUpperCase();
            //身份证号码为15位或者18位，15位时全为数字，18位前17位为数字，最后一位是校验位，可能为数字或字符X。
            if (!(/(^\d{15}$)|(^\d{17}([0-9]|X)$)/.test(str))) {
                //alert('输入的身份证号长度不对，或者号码不符合规定！\n15位号码应全为数字，18位号码末位可以为数字或X。');
                return false;
            }

            //校验位按照ISO 7064:1983.MOD 11-2的规定生成，X可以认为是数字10。
            //下面l分别分析出生日期和校验位
            var len = str.length,
                re,
                arrSplit,
                dtmBirth,
                bGoodDay,
                arrInt,
                arrCh,
                nTemp,
                i;

            if (len == 15) {
                re = new RegExp(/^(\d{6})(\d{2})(\d{2})(\d{2})(\d{3})$/);
                arrSplit = str.match(re);

                //检查生日日期是否正确
                dtmBirth = new Date('19' + arrSplit[2] + '/' + arrSplit[3] + '/' + arrSplit[4]);
                bGoodDay;
                bGoodDay = (dtmBirth.getYear() == Number(arrSplit[2])) && ((dtmBirth.getMonth() + 1) == Number(arrSplit[3])) && (dtmBirth.getDate() == Number(arrSplit[4]));
                if (!bGoodDay) {
                    //alert('输入的身份证号里出生日期不对！');
                    return false;
                } else {
                    //将15位身份证转成18位
                    //校验位按照ISO 7064:1983.MOD 11-2的规定生成，X可以认为是数字10。
                    arrInt = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
                    arrCh = new Array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
                    nTemp = 0;
                    str = str.substr(0, 6) + '19' + str.substr(6, str.length - 6);
                    for (i = 0; i < 17; i++) {
                        nTemp += str.substr(i, 1) * arrInt[i];
                    }
                    str += arrCh[nTemp % 11];
                    return true;
                }
            }
            if (len == 18) {
                re = new RegExp(/^(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)$/);
                arrSplit = str.match(re);

                //检查生日日期是否正确
                dtmBirth = new Date(arrSplit[2] + "/" + arrSplit[3] + "/" + arrSplit[4]);
                bGoodDay;
                bGoodDay = (dtmBirth.getFullYear() == Number(arrSplit[2])) && ((dtmBirth.getMonth() + 1) == Number(arrSplit[3])) && (dtmBirth.getDate() == Number(arrSplit[4]));
                if (!bGoodDay) {
                    //alert(dtmBirth.getYear());
                    //alert(arrSplit[2]);
                    //alert('输入的身份证号里出生日期不对！');
                    return false;
                } else {
                    //检验18位身份证的校验码是否正确。
                    //校验位按照ISO 7064:1983.MOD 11-2的规定生成，X可以认为是数字10。
                    var valnum;
                    arrInt = new Array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2);
                    arrCh = new Array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2');
                    nTemp = 0;
                    for (i = 0; i < 17; i++) {
                        nTemp += str.substr(i, 1) * arrInt[i];
                    }
                    valnum = arrCh[nTemp % 11];
                    if (valnum != str.substr(17, 1)) {
                        //alert('18位身份证的校验码不正确！应该为：' + valnum);
                        return false;
                    }
                    return true;
                }
            }
            return false;
        };

        /*
         ** email check 邮箱校验
         **
         ** @params
         **     str 校验的字符串
         **
         ** @return true/false
         **
         */
        this.emailCheck = function(str) {
            // if (/^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)$/.test(str)) {
            if (/^(\w)+(\.\w+)*@[\w-]+((\.\w+)+)$/.test(str)) {
                return true;
            }
            return false;
        };

        /*
         ** zipcode check 邮政编码校验
         **
         ** @params
         **     str 校验的字符串
         **
         ** @return true/false
         **
         */
        this.zipcodeCheck = function(str) {
            if (/^[0-9]{6}$/.test(str)) {
                return true;
            }
            return false;
        };

        /*
         ** bankno check 银行账号校验
         **
         ** @params
         **     str 校验的字符串
         **
         ** @return true/false
         **
         */
        this.banknoCheck = function(str) {
            if (/^[0-9]{1,}$/.test(str)) {
                return true;
            }
            return false;
        };

        /*
         ** phone check 手机号码校验
         **
         ** @params
         **     str 校验的字符串
         **
         ** @return true/false
         **
         */
        this.phoneCheck = function(str) {
            if (/^[1][0-9]{10}$/.test(str)) {
                return true;
            } else if (/^[5|6|8|9][0-9]{7}$/.test(str)) {
                return true;
            }
            return false;
        };

        /*
         ** money check 检查输入字符串是否符合金额格式
         **
         ** @params
         **     str 校验的字符串
         **
         ** @return true/false
         **
         */
        this.moneyCheck = function(str) {
            var re = /^([1-9][\d]{0,7}|0)(\.[\d]{1,2})?$/;
            if (re.test(str)) {
                return true;
            }
            return false;
        };

        /*
         ** multiple check 检查输入数值是否为另一数值的整数倍
         **
         ** @params
         **     num 校验的数值
         **     num2 整除数
         **
         ** @return true/false
         **
         */
        this.multipleCheck = function(num, num2) {
            if (num && !isNaN(num2)) {
                if (num % num2 == 0) {
                    return true;
                }
            }
            return false;
        };

        /*
         ** get birthday 根据证件号码获取出生日期
         **
         ** @params
         **     str 证件号码
         **
         ** @return 日期YYYY-MM-DD
         **
         */
        this.getBirthday = function(str) {
            var birthdayno,
                birthdaytemp;

            if (str.length == 18) {
                birthdayno = str.substring(6, 14);
            } else if (str.length == 15) {
                birthdaytemp = str.substring(6, 12);
                birthdayno = '19' + birthdaytemp;
            } else {
                return '';
            }
            var birthday = this.dateFormat(birthdayno);

            return birthday;
        };

        /*
         ** get sex 根据年龄求出生日期
         **
         ** @params
         **     age 年龄
         **
         ** @return ageFormat
         **
         */
        this.getDateByAge = function(age) {
            if (age) {
                var date, time, t1, t2, t3, ageFormat1, ageFormat2, ageFormat3, staryear, endyear, yearLength;
                date = new Date();
                endyear = date.getFullYear(); //当前年份
                staryear = endyear - age; //最小投保年限
                time = date.getTime();
                yearLength = [];
                // 获取所有的闰年
                for (var i = staryear; i <= endyear; i++) {
                    if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) {
                        yearLength.push(i);
                    }
                }
                var a = yearLength.length; //获取闰年个数
                // 投保年龄为30天
                if (age == "0") {
                    t1 = time - 30 * 24 * 60 * 60 * 1000;
                    ageFormat1 = new Date(t1);
                    return ageFormat1;

                } else if (age == "18") {
                    t2 = time - age * 365 * 24 * 60 * 60 * 1000 - a * 24 * 60 * 60 * 1000
                    ageFormat2 = new Date(t2);
                    return ageFormat2;
                } else {
                    t3 = time - age * 365 * 24 * 60 * 60 * 1000 - a * 24 * 60 * 60 * 1000 - 365 * 24 * 60 * 60 * 1000 + 24 * 60 * 60 * 1000;
                    ageFormat3 = new Date(t3);
                    return ageFormat3;

                }
            }
        };

        /*
         ** get age 根据出生日期求周岁
         **
         ** @params
         **     birth 出生日期
         **
         ** @return ageFormat
         **
         */
        this.getAgeByBirth = function(birth) {
            if (!birth) {
                return 0;
            }

            if (angular.isString(birth) && birth.indexOf('-') != -1) {
                birth = birth.replace(/\-/g, '/');
            }

            if (isNaN(new Date(birth))) {
                return 0;
            }

            var age = 0;

            var aDate = new Date(),
                thisYear = aDate.getFullYear(),
                thisMonth = aDate.getMonth() + 1,
                thisDay = aDate.getDate();

            var thisBrith = new Date(birth),
                thisBrithy = thisBrith.getFullYear(),
                thisBrithm = thisBrith.getMonth() + 1,
                thisBrithd = thisBrith.getDate();

            if (aDate.getTime() > thisBrith.getTime()) {
                var tempYear = thisYear - thisBrithy,
                    tempMonth = thisMonth - thisBrithm,
                    tempDay = thisDay - thisBrithd;

                age += tempYear;

                if (tempMonth < 0) {
                    age--;
                } else if (tempMonth == 0) {
                    if (tempDay < 0) {
                        age--;
                    }
                }
            }
            return age;
        };

        /*
         ** get sex 根据证件号码获取性别
         **
         ** @params
         **     str 证件号码
         **
         ** @return 1男/2女
         **
         */
        this.getSex = function(str) {
            var sexno,
                sex;

            if (str.length == 18) {
                sexno = str.substring(16, 17);
            } else if (str.length == 15) {
                sexno = str.substring(14, 15);
            } else {
                return '';
            }
            var tempid = sexno % 2;
            if (tempid == 0) {
                sex = false;
            } else {
                sex = true;
            }
            return sex;
        };

        /*
         ** address check 详细地址校验
         **
         ** @params
         **     str 校验的字符串
         **
         ** @return true/false
         **
         */
        this.addressCheck = function(str) {
            if (str) {
                var items = new Array("~", "￥", "……", "（", "）", "+", "=", ",", ".", "，", "。", "`", "!", "！", "；", "‘", "@", "$", "%", "^", "&", "*", "{", "}", "[", "]", "(", ")");
                items.push(":", ";", "'", "|", "\\", "<", ">", "?", "/", "<<", ">>", "||", "//");
                str = str.toLowerCase();

                for (var i = 0; i < items.length; i++) {
                    if (str.indexOf(items[i]) >= 0) {
                        return false;
                    }
                }
                return true;
            } else {
                return false;
            }
        };

        /*
         ** date format 特殊日期格式化
         **
         ** @params
         **     str 待格式化日期字符 'yyyyMMdd'
         **
         ** @return 'yyyy-MM-dd'
         **
         */
        this.dateFormat = function(str) {
            if (str && str.length == 8) {
                str = str.substring(0, 4) + '-' + str.substring(4, 6) + '-' + str.substring(6, 8);
            }
            return str;
        };

    }
})();
